Passed
Push — master ( 88b796...33e64a )
by Andreas
13:35
created

jqGrid.custom.js ➔ add_array   B

Complexity

Conditions 7

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 6
rs 8
c 0
b 0
f 0
cc 7
1
const midcom_jqgrid_presets = {
2
    autowidth: true,
3
    altRows: true,
4
    altclass: 'even',
5
    deselectAfterSort: false,
6
    forceFit: true,
7
    gridview: true,
8
    headertitles: true,
9
    height: 'auto',
10
    hoverrows: true,
11
    shrinkToFit: true,
12
    sortable: true,
13
    autoencode: false,
14
    datatype: 'xml',
15
    iconSet: 'fontAwesome',
16
    jsonReader: {
17
        repeatitems: false,
18
        id: '0'
19
    }
20
};
21
$.extend(true, $.jgrid.cmTemplate, {
22
    title_from_index: {
23
        title: false,
24
        cellattr: function (rowId, cellValue, rawObject, cm, rdata) {
25
            if (cellValue) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if cellValue is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
26
                return ' title="' + rdata['index_' + cm.name] + '"';
27
            }
28
        }
29
    }
30
});
31
32
$.jgrid.defaults = $.extend($.jgrid.defaults, midcom_jqgrid_presets);
33
$.jgrid.search.searchOnEnter = false;
34
$.jgrid.search.defaultSearch = 'cn';
35
36
const midcom_grid_resize = {
37
    timer: false,
38
    containment: '#content-text',
39
    firstrun: true,
40
    add_header_controls: function() {
41
        $('table.ui-jqgrid-btable').jqGrid('setGridParam', {
42
            onHeaderClick: function(gridstate) {
43
                $(this).closest('.ui-jqgrid').find('.ui-jqgrid-titlebar-maximize').toggle(gridstate === 'visible');
44
                $(window).trigger('resize');
45
        }});
46
47
        midcom_grid_resize.attach_maximizer($('.ui-jqgrid-titlebar'));
48
    },
49
    event_handler: function() {
50
        if (midcom_grid_resize.firstrun) {
51
            midcom_grid_resize.firstrun = false;
52
            midcom_grid_resize.add_header_controls();
53
        } else {
54
            if (!midcom_grid_resize.timer) {
55
                $(midcom_grid_resize.containment).addClass('openpsa-resizing');
56
            } else {
57
                clearTimeout(midcom_grid_resize.timer);
58
            }
59
            midcom_grid_resize.timer = setTimeout(midcom_grid_resize.end_resize, 300);
60
        }
61
        if ($('.ui-jqgrid-maximized').length > 0) {
62
            midcom_grid_resize.maximize_height($('.ui-jqgrid-maximized'));
63
            midcom_grid_resize.fill_width($('.ui-jqgrid-maximized'));
64
        } else {
65
            midcom_grid_resize.set_height($('.fill-height'), 'fill');
66
            midcom_grid_resize.set_height($('.crop-height'), 'crop');
67
            midcom_grid_resize.fill_width($('.full-width'));
68
        }
69
    },
70
    end_resize: function() {
71
        midcom_grid_resize.timer = false;
72
        $(midcom_grid_resize.containment).removeClass('openpsa-resizing');
73
    },
74
    attach_maximizer: function(items) {
75
        items.each(function() {
76
            $('<a role="link" class="ui-jqgrid-titlebar-maximize"><span class="fa fa-plus-circle"></span></a>')
77
                .on('click', function() {
78
                    var container = $(this).closest('.ui-jqgrid').parent();
79
80
                    if (container.hasClass('ui-jqgrid-maximized')) {
81
                        $(this).find('span').removeClass('fa-minus-circle').addClass('fa-plus-circle');
82
                        var jqgrid_id = container.find('table.ui-jqgrid-btable').attr('id'),
83
                            placeholder = $('#maximized_placeholder');
84
85
                        try {
86
                            $("#" + jqgrid_id).jqGrid().setGridHeight(placeholder.data('orig_height'));
87
                        } catch(e){}
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
88
89
                        container
90
                            .detach()
91
                            .removeClass('ui-jqgrid-maximized')
92
                            .insertBefore(placeholder)
93
                            .find('.ui-jqgrid-titlebar-close').show();
94
                        placeholder.remove();
95
                        //no container is maximized
96
                        $(midcom_grid_resize.containment).children().removeClass('ui-jqgrid-maximized');
97
                        $(midcom_grid_resize.containment).find('.ui-jqgrid-titlebar-maximize').show();
98
                        $(midcom_grid_resize.containment).children().removeClass('ui-jqgrid-maximized-background');
99
                        $(midcom_grid_resize.containment).css('overflow', 'auto');
100
                    } else {
101
                        $(this).find('span').removeClass('fa-plus-circle').addClass('fa-minus-circle')
102
                        $(midcom_grid_resize.containment).scrollTop(0);
103
                        $('<div id="maximized_placeholder"></div>')
104
                            .data('orig_height', container.find('.ui-jqgrid-bdiv').outerHeight())
105
                            .insertAfter(container);
106
                        container
107
                            .detach()
108
                            .removeClass('ui-jqgrid-maximized-background')
109
                            .addClass('ui-jqgrid-maximized')
110
                            .prependTo($(midcom_grid_resize.containment))
111
                            .find('.ui-jqgrid-titlebar-close').hide();
112
                        $(midcom_grid_resize.containment).children(':not(:first-child)').addClass('ui-jqgrid-maximized-background');
113
                        $(midcom_grid_resize.containment).css('overflow', 'hidden');
114
                    }
115
                    $(window).trigger('resize');
116
                })
117
                .hover(function() {
118
                    $(this).addClass('ui-state-hover');
119
                }, function() {
120
                    $(this).removeClass('ui-state-hover');
121
                })
122
                .appendTo($(this));
123
            if ($(this).closest('.ui-jqgrid').find('.ui-jqgrid-btable').data('maximized')) {
124
                $(this).find('.ui-jqgrid-titlebar-maximize').trigger('click');
125
            }
126
            if ($(this).closest('.ui-jqgrid').find('.ui-jqgrid-btable').is(':hidden')) {
127
                $(this).find('.ui-jqgrid-titlebar-maximize').hide();
128
            }
129
        });
130
    },
131
    fill_width: function(items) {
132
        if (items.length === 0) {
133
            return;
134
        }
135
136
        var new_width;
137
138
        items.each(function(index, item) {
139
            if (items.hasClass('ui-jqgrid-maximized')) {
140
                new_width = $(midcom_grid_resize.containment).width();
141
            } else {
142
                //calculate for each item separately to take care of floating neighbors
143
                new_width = $(item).width();
144
            }
145
            $(item).find('.ui-jqgrid table.ui-jqgrid-btable').each(function() {
146
                let panel = $("#gbox_" + this.id).closest('.ui-tabs-panel');
147
                if (   panel.length > 0
148
                    && panel.hasClass('ui-tabs-hide')) {
149
                    return;
150
                }
151
                try {
152
                    var old_width = $(this).jqGrid().getGridParam('width');
153
                    if (!$(this).data('resized') || new_width != old_width) {
154
                        $(this).jqGrid().setGridWidth(new_width);
155
                        $(this).data('resized', true);
156
                    }
157
                } catch(e){}
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
158
            });
159
        });
160
    },
161
    set_height: function(items, mode) {
162
        if (items.length === 0 || $(midcom_grid_resize.containment).length === 0) {
163
            return;
164
        }
165
166
        var grids_content_height = 0,
167
            container_height = $(midcom_grid_resize.containment).height(),
168
            container_nongrid_height = 0,
169
            visible_grids = 0,
170
            grid_heights = {},
171
            minimum_height = 21;
172
173
        if ($('#org_openpsa_resize_marker_end').length === 0) {
174
            $(midcom_grid_resize.containment)
175
                .append('<div id="org_openpsa_resize_marker_end"></div>')
176
                .prepend('<div id="org_openpsa_resize_marker_start"></div>');
177
        }
178
        container_nongrid_height = $('#org_openpsa_resize_marker_end').position().top - $('#org_openpsa_resize_marker_start').position().top;
179
180
        items.each(function() {
181
            var grid_body = $("table.ui-jqgrid-btable", $(this));
182
            if (grid_body.length > 0) {
183
                var grid_height = grid_body.parent().parent().height(),
184
                    content_height = grid_body.outerHeight();
185
                if (    content_height === 0
186
                    && (   grid_body.jqGrid('getGridParam', 'datatype') !== 'local'
187
                        || (   grid_body.jqGrid('getGridParam', 'treeGrid') === true
188
                            && grid_body.jqGrid('getGridParam', 'treedatatype') !== 'local'))) {
189
                    content_height = 100;
190
                }
191
192
                if (   grid_body.jqGrid('getGridParam', 'gridstate') === 'visible'
193
                    && $(this).is(':visible')) {
194
                    grid_heights[grid_body.attr('id')] = content_height;
195
                    grids_content_height += content_height;
196
                    container_nongrid_height -= grid_height;
197
                    visible_grids++;
198
                }
199
            }
200
        });
201
202
        var available_space = container_height - container_nongrid_height;
203
204
        if (   grids_content_height === 0
205
            || available_space <= minimum_height * visible_grids) {
206
            return;
207
        }
208
209
        if (available_space > grids_content_height && mode !== 'fill') {
210
            $.each(grid_heights, function(grid_id, content_height) {
211
                set_param(grid_id, content_height);
212
            });
213
            return;
214
        }
215
216
        $.each(grid_heights, function(grid_id, content_height) {
217
            var new_height = available_space * (content_height / grids_content_height);
218
            if (new_height < minimum_height) {
219
                available_space -= minimum_height;
220
                grids_content_height -= content_height;
221
                set_param(grid_id, minimum_height);
222
                delete grid_heights[grid_id];
223
            }
224
        });
225
226
        $.each(grid_heights, function(grid_id, content_height) {
227
            var new_height = Math.floor(available_space * (content_height / grids_content_height));
228
            set_param(grid_id, new_height);
229
        });
230
231
        function set_param(grid_id, value) {
232
            let grid = $("#" + grid_id);
233
            if (grid.parent().parent().height() !== value) {
234
                try {
235
                    grid.jqGrid().setGridHeight(value);
236
                } catch(e){}
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
237
                if (grid.data('vScroll')) {
238
                    grid.closest(".ui-jqgrid-bdiv").scrollTop(grid.data('vScroll'));
239
                    grid.removeData('vScroll');
240
                }
241
            }
242
        }
243
    },
244
    maximize_height: function(part) {
245
        var part_height = part.outerHeight(true),
246
            grid_height = $("table.ui-jqgrid-btable", part).parent().parent().outerHeight(),
247
            new_height = $(midcom_grid_resize.containment).height() + grid_height - part_height;
248
249
        try {
250
            $("table.ui-jqgrid-btable", part).jqGrid().setGridHeight(new_height);
251
        }
252
        catch(e){}
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
253
    }
254
};
255
$(window).resize(midcom_grid_resize.event_handler);
256
257
const midcom_grid_editable = {
258
    grid_id: '',
259
    last_added_row: 0,
260
    default_options: {
261
        keys: true,
262
        afterrestorefunc: function(id) {
263
            midcom_grid_editable.toggle(id, false);
264
        },
265
        aftersavefunc: function(id, response) {
266
            //if saved row was new_... then refresh tr-id
267
            if (response.responseText !== undefined) {
268
                var return_values = JSON.parse(response.responseText),
269
                    oldId = return_values.oldid;
270
                if (oldId.substring(0, 4) === 'new_') {
271
                    var pos = $('#' + midcom_grid_editable.grid_id + ' tr[id="' + oldId + '"]').prevAll().length,
272
                        newrow = $('#' + oldId);
273
                    id = return_values.id;
274
275
                    midcom_grid_editable.saveSingleItemPosition(id, pos);
276
277
                    newrow.attr('id', id);
278
                    newrow.find('.row_edit, .row_save, .row_cancel, .row_delete').data('row-id', id);
279
                }
280
            }
281
282
            midcom_grid_editable.toggle(id, false);
283
        },
284
        oneditfunc: function(id) {
285
            midcom_grid_editable.toggle(id, true);
286
        },
287
        successfunc: function(data) {
288
            var return_values = JSON.parse(data.responseText);
289
            return [true, return_values, return_values.id];
290
        },
291
        enable_sorting: false
292
    },
293
    toggle: function(id, edit_mode) {
294
        $("#" + id).find(".row_edit, .row_delete").toggleClass('hidden', edit_mode);
295
        $("#" + id).find(".row_save, .row_cancel").toggleClass('hidden', !edit_mode);
296
        $('#' + id).toggleClass('jqgrid-editing', edit_mode);
297
298
        this.toggle_mouselistener();
299
    },
300
301
    enable_inline: function (grid_id, custom_options) {
302
        var lastsel,
303
            self = this;
304
        self.options = $.extend({}, self.default_options, custom_options);
305
        self.grid_id = grid_id;
306
        $('#' + grid_id).jqGrid('setGridParam', {
307
            onSelectRow: function(id) {
308
                if (id && id !== lastsel) {
309
                    $('#' + id).restoreRow(lastsel);
310
                    lastsel = id;
311
                }
312
                if (!$('#' + id).hasClass('jqgrid-editing')) {
313
                    self.editRow(id);
314
                }
315
            }
316
        });
317
318
        self.add_inline_controls();
319
        var create_button_parameters = {
320
            caption: self.options.button_label || "",
321
            buttonicon: "fa-plus",
322
            onClickButton: function() {
323
                var new_id = 'new_' + self.last_added_row++,
324
                    params = {};
325
326
                if (self.options.enable_sorting) {
327
                    params.position = $('#' + grid_id + ' td[aria-describedby="invoice_items_position"]').length + 1;
328
                }
329
                //create new row; now with a position-value
330
                $('#' + self.grid_id).jqGrid('addRowData', new_id, params, 'last');
331
332
                self.render_buttons(new_id);
333
            }
334
        };
335
        $('#' + grid_id)
336
            .jqGrid('navGrid', "#p_" + grid_id, {add: false, del: false, refresh: false, edit: false, search: false})
337
            .jqGrid('navButtonAdd', "#p_" + grid_id, create_button_parameters);
338
339
        if (self.options.enable_sorting) {
340
            $('#' + grid_id)
341
                .on("sortstop", function() {
342
                    self.refreshItemPositions();
343
                    //Refresh the rows alternately with the style from the class even
344
                    $(this).find("tbody tr.jqgrow").removeClass('even');
345
                    $(this).find("tbody tr.jqgrow:visible:odd").addClass('even');
346
                })
347
                .jqGrid("sortableRows", {helper: "clone"});
348
        }
349
    },
350
    /**
351
     * This function works only if enable_sorting is set true
352
     */
353
    toggle_mouselistener: function() {
354
        if (this.options.enable_sorting) {
355
            var isEdit = $('#' + this.grid_id + ' tr.jqgrid-editing').length > 0;
356
357
            if (isEdit) {
358
                $('#' + this.grid_id).sortable("disable");
359
                $('#' + this.grid_id + ' tbody > .jqgrow').enableSelection();
360
            } else {
361
                $('#' + this.grid_id).sortable("enable");
362
                $('#' + this.grid_id + ' tbody > .jqgrow').disableSelection();
363
            }
364
        }
365
    },
366
    editRow: function(id) {
367
        $('#' + this.grid_id).jqGrid('editRow', id, this.options);
368
        $('#cancel_button_' + id).closest("tr")
369
            .find('textarea, input[type="text"]').filter(':visible').first().focus();
370
    },
371
    saveRow: function(id) {
372
        $('#' + this.grid_id).jqGrid('saveRow', id, this.options);
373
    },
374
    restoreRow: function(id) {
375
        $('#' + this.grid_id).jqGrid('restoreRow', id, this.options);
376
    },
377
    deleteRow: function(id) {
378
        var edit_url = $('#' + this.grid_id).jqGrid('getGridParam', 'editurl'),
379
            rowdata = $('#' + this.grid_id).jqGrid('getRowData', id),
380
            self = this,
381
            callAfterSave = function() {
382
                $('#' + self.grid_id).jqGrid('delRowData', id);
383
                if (typeof self.options.afterdeletefunc === 'function') {
384
                    self.options.afterdeletefunc();
385
                }
386
                if (self.options.enable_sorting) {
387
                    self.refreshItemPositions();
388
                }
389
            };
390
        rowdata.oper = 'del';
391
392
        if (rowdata.id == '') {
393
            callAfterSave();
394
        } else {
395
            $.post(edit_url, rowdata, function() {
396
                callAfterSave();
397
            });
398
        }
399
    },
400
    refreshItemPositions: function() {
401
        var self = this;
402
        $('#' + this.grid_id + ' td[aria-describedby="invoice_items_position"]').each(function(index) {
403
            var idx = index + 1,
404
                oldPos = parseInt($(this).text()),
405
                trId = this.parentNode.id;
406
407
            if (idx !== oldPos) {
408
                // Set new Position-Number in this td
409
                $(this).html(idx);
410
411
                if (trId.substring(0, 4) !== 'new_') {
412
                    self.saveSingleItemPosition(trId, idx);
413
                }
414
            }
415
        });
416
    },
417
    saveSingleItemPosition: function(id, pos) {
418
        $.ajax({
419
            type: 'POST',
420
            url: this.options.position_url,
421
            data: {id: id, position: pos}
422
        });
423
    },
424
    render_buttons: function(rowid) {
425
        var be = "<i class='row_button row_edit fa fa-pencil' data-row-id='" + rowid + "'></i>",
426
            bs = "<i class='row_button row_save hidden fa fa-check' data-row-id='" + rowid + "'></i>",
427
            bc = "<i class='row_button row_cancel hidden fa fa-ban' data-row-id='" + rowid + "'></i>",
428
            bd = "<i class='row_button row_delete fa fa-trash' data-row-id='" + rowid + "'></i>";
429
        $("#" + this.grid_id).jqGrid('setRowData', rowid, {actions: be + bs + bc + bd});
430
    },
431
    add_inline_controls: function() {
432
        var rowids = $("#" + this.grid_id).jqGrid('getDataIDs'),
433
            self = this,
434
            i;
435
436
        for (i = 0; i < rowids.length; i++) {
437
            this.render_buttons(rowids[i]);
438
        }
439
440
        $("#" + this.grid_id).on('click', ".row_edit", function() {
441
            self.editRow(this.dataset.rowId);
442
        });
443
        $("#" + this.grid_id).on('click', ".row_delete", function(e) {
444
            e.stopPropagation();
445
            self.deleteRow(this.dataset.rowId);
446
        });
447
        $("#" + this.grid_id).on('click', ".row_save", function(e) {
448
            e.stopPropagation();
449
            self.saveRow(this.dataset.rowId);
450
        });
451
        $("#" + this.grid_id).on('click', ".row_cancel", function(e) {
452
            e.stopPropagation();
453
            self.restoreRow(this.dataset.rowId);
454
        });
455
    }
456
};
457
458
const midcom_grid_footer = {
0 ignored issues
show
Unused Code introduced by
The constant midcom_grid_footer seems to be never used. Consider removing it.
Loading history...
459
    set_field: function(grid_id, colname, operation) {
460
        let footerdata = {};
461
        footerdata[colname] = $('#' + grid_id).jqGrid('getCol', colname, false, operation);
462
        $('#' + grid_id).jqGrid('footerData', 'set', footerdata);
463
    }
464
};
465
466
const midcom_grid_helper = {
467
    event_handler_added: false,
468
    active_grids: [],
469
    maximized_grid: '',
470
    bind_grouping_switch: function(grid_id) {
471
        var grid = $("#" + grid_id),
472
            group_conf = grid.jqGrid('getGridParam', 'groupingView'),
473
            active = grid.jqGrid('getGridParam', 'grouping'),
474
            expand = false,
475
            toggle = $('<input type="button" value="-">')
476
                .on('click', function() {
477
                    var idPrefix = grid_id + "ghead_0_";
478
479
                    grid.find('.jqgroup').each(function(index, element) {
480
                        if (   (!expand && $(element).find('.tree-wrap').hasClass(group_conf.minusicon))
481
                            || (expand && $(element).find('.tree-wrap').hasClass(group_conf.plusicon))) {
482
                                     grid.jqGrid('groupingToggle', idPrefix + index);
483
                        }
484
                    });
485
                    expand = !expand;
486
                    toggle.val(expand ? '+' : '-');
487
                });
488
489
        $("#chgrouping_" + grid_id)
490
            .val((active) ? group_conf.groupField[0] : 'clear')
491
            .on('change', function() {
492
                var selection = $(this).val(),
493
                    previous = group_conf.groupField[0];
494
495
                if (selection) {
496
                    if (selection == "clear") {
497
                        grid.jqGrid('groupingRemove', true);
498
                    } else {
499
                        grid.jqGrid('groupingGroupBy', selection);
500
                    }
501
502
                    if (   selection !== previous
503
                        && !$(this).find('[value="' + previous + '"]').data('hidden')) {
504
                        // Workaround for https://github.com/tonytomov/jqGrid/issues/431
505
                        grid.jqGrid('showCol', previous);
506
                    }
507
                    $(window).trigger('resize');
508
                }
509
            })
510
            .after(toggle);
511
    },
512
    setup_grid: function (grid_id, config_orig) {
513
        var identifier = 'openpsa-jqgrid#' + grid_id,
514
            saved_values = {},
515
            config = $.extend(true, {}, config_orig);
516
517
        if (   typeof window.localStorage !== 'undefined'
518
            && window.localStorage) {
519
            midcom_grid_helper.active_grids.push(grid_id);
520
            saved_values = JSON.parse(window.localStorage.getItem(identifier));
521
            if (saved_values) {
522
                if (typeof saved_values.custom_keys !== 'undefined') {
523
                    var keys = saved_values.custom_keys;
524
                    delete saved_values.custom_keys;
525
                    $('#' + grid_id).data('vScroll', keys.vScroll);
526
527
                    //only allow one maximized
528
                    if (keys.maximized && midcom_grid_helper.maximized_grid == '') {
529
                        midcom_grid_helper.maximized_grid = grid_id;
530
                    } else {
531
                        keys.maximized = false;
532
                    }
533
                    $('#' + grid_id).data('maximized', keys.maximized);
534
                }
535
                config = $.extend(config, saved_values);
536
            }
537
            if (config.data) {
538
                // if data was removed since last visit, decrease page number
539
                if (config.data.length <= (config.rowNum * config.page)) {
540
                    config.page = Math.ceil(config.data.length / config.rowNum);
541
                }
542
                // if data was added to grid that was empty on last visit, increase page number
543
                else if (config.page === 0) {
544
                    config.page = 1;
545
                }
546
            }
547
            if (midcom_grid_helper.event_handler_added === false) {
548
                $(window).on('unload', midcom_grid_helper.save_grid_data);
549
                midcom_grid_helper.event_handler_added = true;
550
            }
551
        }
552
553
        try {
554
            $('#' + grid_id).jqGrid(config);
555
        } catch (exception) {
556
            if (!$.isEmptyObject(saved_values)) {
557
                $('#' + grid_id).jqGrid('GridUnload');
558
                $('#' + grid_id).jqGrid(config_orig);
559
            } else {
560
                throw exception;
561
            }
562
        }
563
    },
564
    save_grid_data: function() {
565
        var grid_maximized = false;
566
        midcom_grid_helper.active_grids.forEach(function(grid_id) {
567
            if (typeof $('#' + grid_id).jqGrid === 'undefined') {
568
                return;
569
            }
570
            var identifier = 'openpsa-jqgrid#' + grid_id,
571
                grid = $('#' + grid_id),
572
                data = {
573
                    page: grid.jqGrid('getGridParam', 'page'),
574
                    sortname: grid.jqGrid('getGridParam', 'sortname'),
575
                    sortorder: grid.jqGrid('getGridParam', 'sortorder'),
576
                    hiddengrid: grid.closest('.ui-jqgrid-view').find('.ui-jqgrid-titlebar-close .ui-icon').hasClass('ui-icon-circle-triangle-s'),
577
                    custom_keys: {
578
                        vScroll: grid.closest(".ui-jqgrid-bdiv").scrollTop(),
579
                        //only allow one maximized
580
                        maximized: (grid.closest('.ui-jqgrid-maximized').length > 0) && (grid_maximized == grid_id || grid_maximized == false)
0 ignored issues
show
Best Practice introduced by
Comparing grid_maximized to false using the == operator is not safe. Consider using === instead.
Loading history...
581
                    }
582
                };
583
584
            if ($("#chgrouping_" + grid_id).length > 0) {
585
                data.grouping = grid.jqGrid('getGridParam', 'grouping');
586
                data.groupingView = grid.jqGrid('getGridParam', 'groupingView');
587
588
                delete data.groupingView.groups;
589
                delete data.groupingView.lastvalues;
590
            }
591
592
            if (data.custom_keys.maximized) {
593
                grid_maximized = grid_id;
594
            }
595
596
            if (   grid.jqGrid('getGridParam', 'scroll') === 1
597
                && data.custom_keys.vScroll < grid.height()) {
598
                data.page = 1;
599
            }
600
            window.localStorage.setItem(identifier, JSON.stringify(data));
601
        });
602
    }
603
};
604
605
const midcom_grid_csv = {
606
    configs: {},
607
    separator: ';',
608
    add: function (config) {
609
        this.configs[config.id] = config;
610
611
        $('button#' + config.id + '_export').on('click', function(e) {
612
            midcom_grid_csv.prepare_data(config);
613
            e.preventDefault();
614
        });
615
    },
616
    prepare_data: function(config) {
617
        var rows = $('#' + config.id).jqGrid('getRowData'),
618
            field,
619
            data = '';
620
621
        function trim(input) {
622
            let sepExp = new RegExp(midcom_grid_csv.separator),
623
                converted = input
624
                .replace(/\n|\r/g, " ") // remove line breaks
625
                .replace(/\s+/g, " ") // Shorten long whitespace
626
                .replace(/^\s+/g, "") // strip leading ws
627
                .replace(/\s+$/g, "") // strip trailing ws
628
                .replace(/<\/?([a-z][a-z0-9]*)\b[^>]*>/gi, ''); //strip HTML tags
629
630
            if (converted.match(sepExp)) {
631
                return '"' + converted + '"';
632
            }
633
            return converted;
634
        }
635
636
        for (field in config.fields) {
637
            data += trim(config.fields[field]) + this.separator;
638
        }
639
640
        data += '\n';
641
642
        rows.forEach(function(row) {
643
            for (field in config.fields) {
644
                if (typeof row[field] !== 'undefined') {
0 ignored issues
show
introduced by
The variable field is changed by the for-each loop on line 643. Only the value of the last iteration will be visible in this function if it is called outside of the loop.
Loading history...
645
                    data += trim(row[field]) + midcom_grid_csv.separator;
0 ignored issues
show
Bug introduced by
The variable data is changed as part of the for-each loop for example by trim(row.field) + midcom_grid_csv.separator on line 645. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
646
                }
647
            }
648
            data += '\n';
649
        });
650
651
        var blob = new Blob([data], {type: "application/csv;charset=utf-8"});
652
        saveAs(blob, config.filename + ".csv");
653
    }
654
};
655
656
const midcom_grid_batch_processing = {
0 ignored issues
show
Unused Code introduced by
The constant midcom_grid_batch_processing seems to be never used. Consider removing it.
Loading history...
657
    initialize: function(config) {
658
        $('#form_' + config.id).hide();
659
660
        var widgets_to_add = [],
661
            label = config.submit || 'Go',
662
            //build action form and associated widgets
663
            action_select = '<div class="action_select_div" id="' + config.id + '_batch">';
664
        action_select += '<select id="' + config.id + '_batch_select" class="action_select" name="action" size="1">';
665
666
        $.each(config.options, function(key, value) {
667
            action_select += '<option value="' + key + '" >' + value.label + '</option>';
668
            if (typeof value.widget_config !== 'undefined') {
669
                var widget_id = config.id + '__' + key;
670
                widgets_to_add.push({id: widget_id, insertAfter: '#' + config.id + '_batch_select', widget_config: value.widget_config});
671
            }
672
        });
673
        action_select += '</select><input type="submit" name="send" value="' + label + '" style="display: none" /></div>';
674
        $(action_select).appendTo($('#form_' + config.id));
675
676
        widgets_to_add.forEach(function(widget_conf) {
677
            midcom_helper_datamanager2_autocomplete.create_widget(widget_conf);
678
        });
679
680
        $('#' + config.id + '_batch_select').on('change', function(event) {
681
            var selected_option = $(event.target).val();
682
            if (selected_option === 'none') {
683
                $(event.target).nextAll('input[type="submit"]').hide();
684
            } else {
685
                $(event.target).nextAll('input[type="submit"]').show();
686
            }
687
            $('.ui-autocomplete-input').hide();
688
            $('#' + config.id + '_batch').css('display', 'inline');
689
            $('#' + config.id + '__' + selected_option + '_search_input').show();
690
        });
691
692
        //hook action select into grid so that it'll get shown when necessary
693
        $('#' + config.id).jqGrid('setGridParam', {
694
            onSelectRow: function(id, selected, event) {
695
                if ($('#' + config.id).jqGrid('getGridParam', 'selarrrow').length === 0) {
696
                    $('#' + config.id + '_batch').parent().hide();
697
                } else {
698
                    $('#' + config.id + '_batch').parent().show();
699
                }
700
701
                if (selected && event.hasOwnProperty('originalEvent') && event.originalEvent.shiftKey) {
702
703
                    function shift_select(rows) {
0 ignored issues
show
Bug introduced by
The function shift_select is declared conditionally. This is not supported by all runtimes. Consider moving it to root scope or using var shift_select = function() { /* ... */ }; instead.
Loading history...
704
                        let started = false;
705
                        rows.get().reverse().forEach(function(row) {
706
                            if (started) {
707
                                if (!$(row).hasClass('ui-state-highlight')) {
708
                                    $(row).find('td.td_cbox input').trigger('click');
709
                                }
710
                            } else {
711
                                started = $(row).hasClass('ui-state-highlight');
712
                            }
713
                        });
714
                    }
715
716
                    let clicked_row = $('#' + config.id + ' tr#' + id);
717
                    if (clicked_row.prevAll('.ui-state-highlight').length > 0) {
718
                        shift_select(clicked_row.prevAll(':not(.jqgroup)'));
719
                    } else if (clicked_row.nextAll('.ui-state-highlight').length > 0) {
720
                        shift_select(clicked_row.nextAll(':not(.jqgroup)'));
721
                    }
722
                }
723
724
                $(window).trigger('resize');
725
            },
726
            onSelectAll: function(rowids, status) {
727
                if (!status) {
728
                    $('#' + config.id + '_batch').parent().hide();
729
                } else {
730
                    $('#' + config.id + '_batch').parent().show();
731
                }
732
                $(window).trigger('resize');
733
            }
734
        });
735
736
        // We use regular post instead of ajax to get browser's busy indicator
737
        $("#form_" + config.id).on('submit', function() {
738
            function add_array(field, data) {
739
                for (var i = 0; i < data.length; i++) {
740
                    $('<input type="hidden" name="' + field + '[]" value="' + data[i] + '" />')
741
                        .appendTo('#form_' + config.id);
742
                }
743
            }
744
            add_array('entries', $("#" + config.id).jqGrid('getGridParam', 'selarrrow'));
745
746
            var action = $("#form_" + config.id + ' select[name="action"]').val(),
747
                autocomplete = $("#" + config.id + '__' + action + '_selection');
748
749
            if (autocomplete.length > 0 && autocomplete.val().length) {
750
                add_array('selection', JSON.parse(autocomplete.val()));
751
            } else if (config.options[action].value) {
752
                $('<input type="hidden" name="value" value="' + config.options[action].value + '" />')
753
                    .appendTo('#form_' + config.id);
754
            }
755
        });
756
    }
757
};
758
759
const midcom_grid_row_actions = {
760
    update_totals: function(table, config) {
761
        var total = 0,
762
            row_sum,
763
            totals_field = table.closest('.ui-jqgrid-view').find('.ui-jqgrid-ftable .' + config.totals_field);
764
765
        table.find('tbody tr').not('.jqgfirstrow').each(function() {
766
            row_sum = parseFloat($(this).find('.' + config.totals_field).prev().text());
767
            if (isNaN(row_sum)) {
768
                return;
769
            }
770
771
            total += row_sum;
772
        });
773
774
        totals_field.text($.fn.fmatter.number(total, $.jgrid.locales[$.jgrid.defaults.locale].formatter));
775
    },
776
777
    process: function(button, action, config) {
778
        button.attr('disabled', 'disabled');
779
        var id = button.parent().parent().attr('id');
780
        $.post(config.url + action + '/', {id: id}, function(data) {
781
            if (data.success !== false) {
782
                var old_grid = button.closest('.ui-jqgrid-btable'),
783
                    regex = new RegExp(data.old_status),
784
                    row_data = old_grid.getRowData(id),
785
                    new_grid = $('#' + old_grid.attr('id').replace(regex, data.new_status));
786
787
                old_grid.delRowData(id);
788
                midcom_grid_row_actions.update_totals(old_grid, config);
789
790
                if (new_grid.length < 1) {
791
                    // Grid is not present yet, reload
792
                    window.location.reload();
793
                    return;
794
                }
795
796
                if (new_grid.jqGrid('getGridParam', 'datatype') === 'local') {
797
                    row_data.action = data.action;
798
                    data.updated.forEach(function(item) {
799
                        row_data[item[0]] = item[1];
800
                    });
801
                    new_grid.addRowData(row_data.id, row_data, "last");
802
                    midcom_grid_row_actions.update_totals(new_grid, config);
803
                } else {
804
                    new_grid.trigger('reloadGrid');
805
                }
806
                $(window).trigger('resize');
807
            }
808
809
            data.messages.forEach(function(message) {
810
                $.midcom_services_uimessage_add(message);
811
            });
812
        })
813
            .fail(function(response) {
814
                if (response.status === 403) {
815
                    // most probably our login session expired. reload
816
                    location.href = location.href;
817
                } else {
818
                    $.midcom_services_uimessage_add({
819
                        type: 'error',
820
                        title: response.statusText,
821
                        message: response.responseText
822
                    });
823
                }
824
            });
825
    },
826
827
    init: function(config) {
828
        config.actions.forEach(function(action) {
829
            $('#' + config.identifier + '.ui-jqgrid-btable')
830
                .on('click', 'button.' + action, function() {
831
                    midcom_grid_row_actions.process($(this), action, config);
832
                });
833
        });
834
    }
835
};
836